#!/usr/bin/python
"""
Front end for Tama.
"""

## standard library imports
import os
import sys
import time
import json
import random
import argparse

## installed modules
import inflect

## local modules
from . import config
from . import gotchi
from . import vtils
from . import gibber

__version__ = "0.1"
__author__  = "dogfeet@pm.me"

## data

# config.TAMA_PATH, config.TAMA_CONFIG, config.TAMA_DIR

## checks

def validate_setup():
    """
    Steps through directory structure and corrects any errors. If the tama
    directory is not found, call the initialization.

    todo: this is really rough and should be more thorough?
    """

    if not os.path.exists(config.TAMA_PATH):
        return init()
    elif not valid_config():
        return make_config()

    return True

def valid_config():
    """
    Checks configuration file and returns True or False.

    todo: this isn't really implemented at all
    """

    config.TAMA_CONFIG = vtils.open_json_as_dict(config.TAMA_CONFIGFILE)
    #print(config.TAMA_CONFIG)
    return os.path.exists(config.TAMA_CONFIGFILE)

## init

def init():
    """
    Starts a fresh instance of tama.
    """

    os.mkdir(config.TAMA_PATH)
    os.mkdir(config.TAMA_DIR)

    readme = open(os.path.join(config.TAMA_PATH, "README.txt"), 'w')
    readme.write(config.config_readme)
    readme.close()

    make_config()
    find_egg()

    return

def make_config():
    """
    Generates user config file.
    """

    config.TAMA_CONFIG = {
            "held": [],
            "released": [],
            "passed": [],
            "completed": []
            }

    save_config()

    return

def find_egg():
    """
    Find a new egg.

    This generates a fresh tama, then steps the player through emotional
    response detection and provides an option to collect or not collect an egg.
    Uncollected eggs are still recorded, but are not immediately accessible to
    the player.

    This loops until the player accepts an egg (can be bypassed if player hits a
    keyboard interrupt).
    """

    tama = gotchi.Tama()
    tama.spawn()

    print("""
You find a strange egg in the {terrain}. It looks {description}.

What feeling is strongest within you right now?

         (A)NXIOUS
         (B)RAVE
         (C)AUTIOUS\
""".format(terrain=tama.locale, description=tama.egg))

    choice = ""

    while choice not in config.feelings.keys():
        choice = input("\n(type a, b, or c and press 'enter')\n> ")
        if len(list(choice)) > 0:
            choice = list(choice)[0]

    # todo: should temperament be set before egg is collected or rejected? or
    # should wild eggs not have a temperament?

    tama.set_temperament(config.feelings.get(choice)[1])

    collected = vtils.input_yn("\nWill you collect this egg?")
    
    if collected:
        config.TAMA_CONFIG.get("held").append(tama.true_name)
        save_config()
        #print(tama.true_name)
        #print(config.TAMA_CONFIG)
        print("""
{adj}, you gather it into your arms.

This egg is now under your care.
""".format(adj=config.feelings.get(choice)[2].capitalize()))
    else:
        print("\nYou pass up the {description} egg of the {terrain} and move on.\n\n".format(description=tama.egg, terrain=tama.locale))
        vtils.pause(1)
        print("\n\n")
        #tama.destroy()
        config.TAMA_CONFIG.get("passed").append(tama.true_name)
        save_config()
        find_egg()

### data management

def save_config():
    """
    Saves current config to disk.
    """

    vtils.write_dict_as_json(config.TAMA_CONFIGFILE, config.TAMA_CONFIG)

def get_args():
    """
    Create and manage arg parser.
    """

    parser = argparse.ArgumentParser(
            description = "A command line virtual pet. Run with no arguments to interact with your pet."
            )

    parser.add_argument(
            "--version", "-v",
            action = "store_true",
            help = "Shows version and quits."
            )

    parser.add_argument(
            "--cybre",
            type = str,
            help = "This is a secret."
            )

    return parser.parse_args()

### interactions

def name_tama(tama):
    """
    Name a tama.
    """

    if tama.interaction_ready() or not tama.false_name:
        new_name = ""

        while not new_name:
            new_name = input("What would you like to name this {}?\n> ".format(tama.status))
        print("\n")
        print(tama.grant_false_name(new_name))
    else:
        print("This {} isn't ready to accept a name right now.".format(tama.status))

    return

def squeeze_tama(tama):
    """
    Squeeze a tama.
    """
    if tama.interaction_ready():
        print(tama.squeeze())
    else:
        print(random.choice(config.no_squeeze))

    return

def call_tama(tama):
    """
    Call tama's name, which may have a number of effects, but is primarily to
    get a name check in.
    """

    if tama.false_name:
        if tama.interaction_ready():
            print(tama.call())
        else:
            print(random.choice(config.call_fail))
    else:
        print("Though you may wish to speak this {}'s name, you must assign it one first.".format(tama.status))

def ignore_tama(tama):
    """
    Do nothing and exit.

    todo: report tama's check-in ratio?
    """

    print("You leave the {} alone, for now.".format(tama.status))

def release_tama(tama):
    """
    Releases the tama into the wild, asking the user to retype a code word for
    confirmation.

    Released tamas do not just disappear; they get added to a list of known
    released tamas. Future work may involve reuniting with them, especially if
    there's some sense of wild tama autonomy.
    """

    tama_desc = tama.status
    if tama.false_name:
        tama_desc = tama_desc + " named " + tama.false_name.capitalize()

    codeword = gibber.long_word().upper()

    print("""\
Releasing this {desc} from your care may not be recoverable.

If you are certain of this decision, carefully speak the incantation below:

                    {codeword}

Otherwise, speak any other word to declare that you have changed your mind.
""".format(desc=tama_desc, codeword=codeword))

    answer = input("> ")

    if answer == codeword:
        config.TAMA_CONFIG.get("released", []).append(tama.true_name)
        if tama.status == "carcass":
            config.TAMA_CONFIG.get("completed", []).append(tama.true_name)
        config.TAMA_CONFIG.get("held").pop(0)
        save_config()

        print("""
With one determined motion, you release the {} from your care.
You experience a deep pang during the separation, but it will slowly fade.
""".format(tama_desc))
        vtils.pause(1)
        print("""

You will not forget the lessons you have learned from this experience.\
""")
    else:
        print("\nThe {} remains in your care, for now.".format(tama_desc))

### main processes

def menu_gaze(active_tama):
    """
    Options from the position of gazing upon a specific tama.
    """

    options = [
            "IGNORE",
            "SQUEEZE",
            "CALL",
            "NAME",
            "RELEASE",
            ]

    print(active_tama.self_report())
    print("\n")
    vtils.pause(1)
    print("\n")

    print("Considering some possibilities, the following actions occur to you:\n")
    vtils.print_menu(options)
    choice = vtils.list_select(options, "What will you do next? (select a number)\n> ")

    print("\n")

    if choice == 0:
        ignore_tama(active_tama)
    elif choice == 1:
        squeeze_tama(active_tama)
    elif choice == 2:
        call_tama(active_tama)
        #active_tama.age_up()
        #print(active_tama.status)
    elif choice == 3:
        name_tama(active_tama)
    elif choice == 4:
        release_tama(active_tama)

    return

def main():
    """Main entry point. Called on program start."""

    args = get_args()
    if args.version:
        return print(__version__)

    if validate_setup():
        ## begin game

        # if no eggs are held, launch egg finder and end round; otherwise, load
        # first held egg

        # todo: have egg selector when multiple eggs gets implemented/unlocked
        if len(config.TAMA_CONFIG.get("held", [])) < 1:
            return find_egg()
        else:
            active_tama = gotchi.Tama()
            active_tama.load(config.TAMA_DIR, config.TAMA_CONFIG.get("held")[0])

        ## name check
        if active_tama.false_name == "":
            print("You have not yet named the {description} egg from the {terrain}.".format(description=active_tama.egg,
                terrain=active_tama.locale))
            naming = vtils.input_yn("\nWill you name this egg now?")

            if naming:
                return name_tama(active_tama)

        ## check for cheat code

        if args.cybre == "ipakyno":
            active_tama.set_temperament("cybre")
            print(active_tama.true_name.upper())

        ## then drop into main actions
        if active_tama.age_check():
            print("""\
You suddenly feel a tingle of excitement, and are compelled to place the {} in a
comfortable spot the {}.""".format(active_tama.status, active_tama.locale))
            print("\n\n")
            vtils.pause(1)
            print("\n\n")
            print(active_tama.age_up())
            print("\n\n<press enter to continue>")
            nothing = input()
        return menu_gaze(active_tama)

##########

if __name__ == '__main__':
    sys.exit(main())
